package db;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import utils.Configuration;

public abstract class Entity {

	public Entity() {
	}

	public Entity(int id) {
		_id = id;
	}

	protected int _id = -1;
	protected static final String configKey = "";

	public int getId() {
		return _id;
	}

	public EntityCollection selectAll() {
		EntityCollection c = new EntityCollection<Entity>();
		try {
			Connection conn = MySqlHandler.getConnection(Configuration.getConfig(configKey).getConnStr());
			ResultSet rs = MySqlHandler.querySelect(conn, getTblname());
			while (rs.next()) {
				c.add(map(rs));
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}

		return c;
	}

	public Entity retrieve(int id) {
		try {
			Connection conn = MySqlHandler.getConnection(Configuration.getConfig(configKey).getConnStr());
			ResultSet rs = MySqlHandler.querySelect(conn, getTblname(), getIdCol() + " = " + id);
			if (rs.next()) {
				this.map(rs);
			} else {
				_id = -1;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return this;
	}

	public void save() {
		try {
			Connection conn = MySqlHandler.getConnection(Configuration.getConfig(configKey).getConnStr());
			String cmd = "";
			ResultSet rs = MySqlHandler.querySelect(conn, getTblname(), getIdCol() + " = " + getId());
			if (rs.next()) {
				cmd = MySqlHandler.getUpdateCommand(getTblname(), getNoCols(), getIdCol(), getId());
			} else {
				cmd = MySqlHandler.getInsertCommand(getTblname(), getNoCols());
			}
			PreparedStatement ps = MySqlHandler.getPreparedStatement(conn, cmd);
			fillPreparedParams(ps);
			MySqlHandler.update(conn, ps);
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	protected Entity map(ResultSet rs) {
		Entity ent = null;
		try {
			ent = mapToObj(rs);
			ent._id = rs.getInt(getIdCol());
		} catch (Exception e) {
			e.printStackTrace();
		}

		return ent;
	}
	
	 // No columns exclusive of the id column
	protected abstract int getNoCols();

	protected abstract void fillPreparedParams(PreparedStatement ps);

	protected abstract String getIdCol();

	protected abstract String getTblname();

	protected abstract Entity mapToObj(ResultSet rs);
}
